package detect

import (
	"errors"
	"os/exec"
	"strings"
)

/**
使用命令行检测后端数据库节点的可写状态
在MGR中从当前节点查询本节点状态可能并不准确
例如：发生网络分区，从当前节点查看状态为ONLINE，但从其他节点查看，则当前可能为ERROR状态，
代码并未考虑这个情况，后续可增加对一个节点可写状态判断需要与其他节点的状态查询综合考虑
*/
var CMD = "mysql"

func State(detectSql string, user string, pass string, port string, ip string, host string, cluster string) (bool, error) {
	ok, _ := CommandOk(CMD)
	if ok {
		sqlComLine := CMD + " -u" + user + " -p" + pass + " -h" + ip + " -P" + port + " -NBe \""
		if cluster == "greatdb" {
			sqlComLine += detectSql + " WHERE (HOST=" + "'" + ip + "'" + " OR HOST=" + "'" + host + "'" + ") AND PORT=" + "'" + port + "'" + "\""
		} else if cluster == "mgr" {
			sqlComLine += detectSql + " WHERE (MEMBER_HOST=" + "'" + ip + "'" + " OR MEMBER_HOST=" + "'" + host + "'" + ") AND MEMBER_PORT=" + "'" + port + "'" + "\""
		}
		cmd := exec.Command("bash", "-c", sqlComLine)
		out, err := cmd.CombinedOutput()
		rest := strings.Replace(strings.Replace(string(out), "\n", "", -1), "\r", "", -1)
		if err == nil {
			x := strings.Split(rest, ".")
			if x[len(x)-1] == "ONLINE" {
				return true, nil
			} else {
				return false, errors.New("instance is exists but cannot write")
			}
		}
		return false, err
	} else {
		return false, errors.New("cannot detect instance state")
	}
}

func CommandOk(c string) (bool, error) {
	command := "which " + c
	cmd := exec.Command("bash", "-c", command)
	out, err := cmd.CombinedOutput()
	if err == nil {
		context := strings.Fields(strings.Replace(string(out), "\n", "", -1))
		if len(context) > 2 {
			if context[1] == "no" {
				return false, nil
			}
		}
		return true, nil
	}
	return false, err
}
